package com.ruoyi.business.weipinhuiController;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.enums.SaveType;
import com.ruoyi.common.utils.EncrypDES;
import com.ruoyi.common.utils.GetUrlParam;
import com.ruoyi.common.utils.OtherUtils;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.common.utils.ip.IpUtils;
import com.ruoyi.system.domain.vo.R;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("ownJISUApi")
public class JiSuController {

    @Autowired
    private RedisCache redisCache;

    private final static String CLASSESEN = "weipinhui";

    private final static String CALLBACK_URLBASE = "http://c2.wkanx.com/tracking";


    /**
     * http://47.94.2.84:9185/ownJISUApi/crowdStrategy?channelId=6500796032829440&dmpid=__SID__&oaid=__OAID__&imei=__IMEI__&idfa=__IDFA__
     * @param request
     * @return
     * @throws Exception
     */
    @Log(title = "唯品会", businessType = BusinessType.RTA, esIndex = "weipinhui_log", saveType = SaveType.ES)
    @RequestMapping("/crowdStrategy")
    public Object crowdStrategy(HttpServletRequest request) throws Exception {
        String queryString = request.getQueryString();
        String channelId = request.getParameter("channelId");
        String dmpid = request.getParameter("dmpid");
        if(StringUtils.isBlank(channelId) || "null".equals(channelId)){
            return R.failure().msg("channelId不能为空");
        }
        if(StringUtils.isBlank(dmpid) || "null".equals(dmpid)){
            return R.failure().msg("dmpid不能为空");
        }

        Map<String, Object> baseParamsMap = GetUrlParam.queryStrToMap(queryString);

        baseParamsMap.remove("channelId");
        baseParamsMap.remove("dmpid");

        Map<String, Object> channelDetail = redisCache.getCacheMapValue(CLASSESEN+"Cache", channelId);
        if(channelDetail == null){
            return R.failure().msg("channelId不正确");
        }
        if("0".equals(channelDetail.get("isopen")+"")){
            return R.failure().msg("channelId未开启");
        }
        String url = channelDetail.get("rta_adress") + "";
        String requestAddress = GetUrlParam.getRequestAddress(url);
        String staticParameters = GetUrlParam.TruncateUrlPage(url);
        Map<String, Object> staticParamsMap = GetUrlParam.queryStrToMap(staticParameters);
        baseParamsMap.putAll(staticParamsMap);



        String imei = getMapValue(baseParamsMap, "imei");
        String oaid = getMapValue(baseParamsMap, "oaid");
        String idfa = getMapValue(baseParamsMap, "idfa");
        if(StringUtils.isNotBlank(imei) && !"null".equals(imei) && !"__IMEI__".equals(imei)) {
            baseParamsMap.put("deviceId", imei);
            baseParamsMap.put("deviceType", "2");
        }else if(StringUtils.isNotBlank(oaid) && !"null".equals(oaid) && !"__OAID__".equals(oaid)) {
            baseParamsMap.put("deviceId", oaid);
            baseParamsMap.put("deviceType", "5");
        }else if(StringUtils.isNotBlank(idfa) && !"null".equals(idfa) && !"__IDFA__".equals(idfa)) {
            baseParamsMap.put("deviceId", idfa);
            baseParamsMap.put("deviceType", "1");
        }



        String ua = baseParamsMap.get("ua") + "";
        String ip = baseParamsMap.get("ip") + "";
        if(StringUtils.isNotBlank(ua) && !"null".equals(ua)){
            ua = URLDecoder.decode(ua, Constants.UTF8);
        }else{
            ua = null;
        }
        if(StringUtils.isNotBlank(ip) && !"null".equals(ip)){
        }else{
            ip = null;
        }

        List<String> tempList = new ArrayList<>();
        for(String key: baseParamsMap.keySet()){
            String value = baseParamsMap.get(key) + "";
            if(value.startsWith("__") && value.endsWith("__")){
                value = "";
            }
            tempList.add(key+"="+value);
        }
        String requestParameters = String.join("&", tempList);


        String reportResultsStr = "";
        reportResultsStr = HttpUtils.sendGet(requestAddress, requestParameters , ip, ua);

        JSONObject reportResults = null;
        try {
            reportResults = JSONObject.parseObject(reportResultsStr);
            if(reportResults.getInteger("code") == 200){
                return 1;
            }
            return 0;
        }catch (Exception e){
            e.printStackTrace();
        }
        return 0;
    }


    /**
     * http://www.ssptqt.com/ownJISUApi/rta?channelId=6500796032829440&dmpid=__SID__&click_id=__SID__&idfa=__IDFA__&imei_md5=__HASH_IMEI__&oaid=__OAID__&os=__OS__&android_id_md5=__ANDROID_ID__&ip=&ua=
     * @param request
     * @return
     * @throws Exception
     */
    @Log(title = "唯品会", businessType = BusinessType.RTA, esIndex = "weipinhui_log", saveType = SaveType.ES)
    @RequestMapping("/rta")
    public Object rtaSend(HttpServletRequest request) throws Exception {
        String queryString = request.getQueryString();
        String channelId = request.getParameter("channelId");
        String dmpid = request.getParameter("dmpid");
        if(StringUtils.isBlank(channelId) || "null".equals(channelId)){
            return R.failure().msg("channelId不能为空");
        }
        if(StringUtils.isBlank(dmpid) || "null".equals(dmpid)){
            return R.failure().msg("dmpid不能为空");
        }

        Map<String, Object> baseParamsMap = GetUrlParam.queryStrToMap(queryString);

        baseParamsMap.remove("channelId");
        baseParamsMap.remove("dmpid");

        Map<String, Object> channelDetail = redisCache.getCacheMapValue(CLASSESEN+"Cache", channelId);
        if(channelDetail == null){
            return R.failure().msg("channelId不正确");
        }
        if("0".equals(channelDetail.get("isopen")+"")){
            return R.failure().msg("channelId未开启");
        }
        String url = channelDetail.get("rta_adress") + "";
        String requestAddress = GetUrlParam.getRequestAddress(url);
        String staticParameters = GetUrlParam.TruncateUrlPage(url);
        Map<String, Object> staticParamsMap = GetUrlParam.queryStrToMap(staticParameters);
        baseParamsMap.putAll(staticParamsMap);


        String ua = baseParamsMap.get("ua") + "";
        String ip = baseParamsMap.get("ip") + "";
        if(StringUtils.isNotBlank(ua) && !"null".equals(ua)){
            ua = URLDecoder.decode(ua, Constants.UTF8);
        }else{
//            ua = null;
            //request 获取 ua
            ua = request.getHeader("User-Agent");
            baseParamsMap.put("ua", URLEncoder.encode(ua, Constants.UTF8));
        }
        if(StringUtils.isNotBlank(ip) && !"null".equals(ip)){
        }else{
//            ip = null;
            //request 获取 ip
            ip = IpUtils.getIpAddr(request);
        }


        String os = getMapValue(baseParamsMap, "os");
        baseParamsMap.put("reqId", dmpid);

        if("0".equals(os)){
            //安卓
            baseParamsMap.put("os", "2");
        }else if("1".equals(os)){
            //ios
            baseParamsMap.put("os", "1");
        }



        List<String> tempList = new ArrayList<>();
        for(String key: baseParamsMap.keySet()){
            String value = baseParamsMap.get(key) + "";
            if(value.startsWith("__") && value.endsWith("__")){
                value = "NULL";
            } else if (StringUtils.isBlank(value) || "null".equals(value)) {
                value = "NULL";
            }
            tempList.add(key+"="+value);
        }
        String requestParameters = String.join("&", tempList);
        String reportResultsStr = HttpUtils.sendGet(requestAddress, requestParameters, ip, ua);
        JSONObject reportResults = null;
        try {
            reportResults = JSONObject.parseObject(reportResultsStr);
            if(reportResults.getInteger("code") == 200){
                JSONObject data = reportResults.getJSONObject("data");
                if(data.getInteger("bidStatus") == 1){
                    return 1;
                }
            }
            return reportResults==null?"":reportResults;
        }catch (Exception e){
            e.printStackTrace();
        }
        return reportResultsStr;
    }




    /**
     * http://www.ssptqt.com/ownJISUApi/send?channelId=6500796032829440&dmpid=__SID__&click_id=__SID__&idfa=__PLAIN_IDFA__&idfa_md5=__IDFA__&imei_md5=__IMEI__&oaid=__OAID__&oaid_md5=__HASH_OAID__&os=__OS__&ts=__STIME__&mac=__PLAIN_MAC__&mac_md5=__MAC__&android_id_md5=__ANDROID_ID__&cid=__CID__&ip=&ua=
     * @param request
     * @return
     * @throws Exception
     */
    @Log(title = "唯品会", businessType = BusinessType.ESCALATION, esIndex = "weipinhui_log", saveType = SaveType.ES)
    @RequestMapping("/send")
    public Object send(HttpServletRequest request) throws Exception {
        String queryString = request.getQueryString();
        String channelId = request.getParameter("channelId");
        String dmpid = request.getParameter("dmpid");
        if(StringUtils.isBlank(channelId) || "null".equals(channelId)){
            return R.failure().msg("channelId不能为空");
        }
        if(StringUtils.isBlank(dmpid) || "null".equals(dmpid)){
            return R.failure().msg("dmpid不能为空");
        }

        Map<String, Object> baseParamsMap = GetUrlParam.queryStrToMap(queryString);

        baseParamsMap.remove("channelId");
        baseParamsMap.remove("dmpid");

        Map<String, Object> channelDetail = redisCache.getCacheMapValue(CLASSESEN+"Cache", channelId);
        if(channelDetail == null){
            return R.failure().msg("channelId不正确");
        }
        if("0".equals(channelDetail.get("isopen")+"")){
            return R.failure().msg("channelId未开启");
        }
        String url = channelDetail.get("request_address") + "";
        String requestType = channelDetail.get("request_type") + "";
        String requestAddress = GetUrlParam.getRequestAddress(url);
        String staticParameters = GetUrlParam.TruncateUrlPage(url);
        Map<String, Object> staticParamsMap = GetUrlParam.queryStrToMap(staticParameters);
        baseParamsMap.putAll(staticParamsMap);


        String ua = baseParamsMap.get("ua") + "";
        String ip = baseParamsMap.get("ip") + "";
        if(StringUtils.isNotBlank(ua) && !"null".equals(ua)){
            ua = URLDecoder.decode(ua, Constants.UTF8);
        }else{
//            ua = null;
            //request 获取 ua
            ua = request.getHeader("User-Agent");
        }
        if(StringUtils.isNotBlank(ip) && !"null".equals(ip)){
        }else{
//            ip = null;
            //request 获取 ip
            ip = IpUtils.getIpAddr(request);
        }


        String callbackClientId = channelDetail.get("callback_clientid") + "";
        String callbackSecretkey = channelDetail.get("callback_secretkey") + "";
        String idfaMd5 = getMapValue(baseParamsMap, "idfa_md5");
        String idfa = getMapValue(baseParamsMap, "idfa");
        String imeiMd5 = getMapValue(baseParamsMap, "imei_md5");
        String mac = getMapValue(baseParamsMap, "mac");
        String macMd5 = getMapValue(baseParamsMap, "mac_md5");
        String os = getMapValue(baseParamsMap, "os");
        String cid = getMapValue(baseParamsMap, "cid");
        String ts = getMapValue(baseParamsMap, "ts");
        String oaid = getMapValue(baseParamsMap, "oaid");



        LinkedHashMap<String, String> callbackMap = new LinkedHashMap<>();
        callbackMap.put("cid", cid);
        callbackMap.put("clientid", callbackClientId);
        callbackMap.put("clientkey", callbackSecretkey);
        callbackMap.put("idfa", idfaMd5);
        callbackMap.put("imei", imeiMd5);
        callbackMap.put("mac", macMd5);
        callbackMap.put("os", os);
        //sid代表请求标识
        callbackMap.put("sid", dmpid);
        //stime为上报时间戳。 上传过来的参数为ts
        callbackMap.put("stime", ts);

        List<String> tempList = new ArrayList<>();
        for(String key: callbackMap.keySet()){
            tempList.add(key+"="+callbackMap.get(key));
        }
        String callbackParams = String.join("&", tempList);
        EncrypDES encrypDES = new EncrypDES();
        String callbackBase = OtherUtils.getServerUrl(request) + "ownJISUApi/callback/"+channelId+"/"+dmpid+"/";
        String encrypt_u = encrypDES.encrypt(CALLBACK_URLBASE);
        String nu = callbackBase + encrypt_u + "?"+callbackParams;
        baseParamsMap.put("callback_url", URLEncoder.encode(nu, Constants.UTF8));


        baseParamsMap.put("click_id", dmpid);

        if("0".equals(os)){
            //安卓
            baseParamsMap.put("os", "2");
        }else if("1".equals(os)){
            //ios
            baseParamsMap.put("os", "1");
        }

        if(StringUtils.isNotBlank(ts) && !"null".equals(ts) && !"__STIME__".equals(ts)) {
            // wifi ts为毫秒，上游极速需要毫秒
            baseParamsMap.put("ts", ts+"000");
        }



        tempList = new ArrayList<>();
        for(String key: baseParamsMap.keySet()){
            String value = baseParamsMap.get(key) + "";
            if(value.startsWith("__") && value.endsWith("__")){
                value = "NULL";
            } else if (StringUtils.isBlank(value) || "null".equals(value)) {
                value = "NULL";
            }
            tempList.add(key+"="+value);
        }
        String requestParameters = String.join("&", tempList);
        String reportResultsStr = "";
        if("POST".equals(requestType)){
            reportResultsStr = HttpUtils.sendPost(requestAddress, requestParameters, ip, ua);
        }else{
            reportResultsStr = HttpUtils.sendGet(requestAddress, requestParameters, ip, ua);
        }
        JSONObject reportResults = null;
        try {
            reportResults = JSONObject.parseObject(reportResultsStr);
            return reportResults==null?"":reportResults;
        }catch (Exception e){
            e.printStackTrace();
        }
        return reportResultsStr;
    }




    private String getMapValue(Map<String, Object> map, String key){
        if(map == null){
            return "";
        }
        if(map.get(key) == null){
            return "";
        }
        return map.get(key)+"";
    }


    @Log(title = "唯品会", businessType = BusinessType.CALLBACK, esIndex = "weipinhui_log", saveType = SaveType.ES)
    @RequestMapping("/callback/{channelId}/{dmpid}/{encryptedUrl}")
    public Object send(HttpServletRequest request, @PathVariable("encryptedUrl") String encryptedUrl) throws Exception {
        String queryString = request.getQueryString();
        Map<String, Object> queryMap = GetUrlParam.queryStrToMap(queryString);
        String eventType = queryMap.get("operateType") + "";
        if("0".equals(eventType)){
            //上报 -> 关键行为
            queryMap.put("event_type", 6);
        }else if("1".equals(eventType)) {
            //激活
            queryMap.put("event_type", 1);
        }else if("2".equals(eventType)) {
            //注册
            queryMap.put("event_type", 2);
        }else if("3".equals(eventType)) {
            //次日留存
            queryMap.put("event_type", 5);
        }


        LinkedHashMap<String, String> callbackMap = new LinkedHashMap<>();
        callbackMap.put("cid", getMapValue(queryMap, "cid"));
        callbackMap.put("clientid", getMapValue(queryMap, "clientid"));
//        callbackMap.put("event_type", getMapValue(queryMap, "event_type"));
        callbackMap.put("idfa", getMapValue(queryMap, "idfa"));
        //下游没有imei, 但是有imei_md5
        callbackMap.put("imei", getMapValue(queryMap, "imei"));
        //下游的mac是进行MD5加密过的就是上游的mac_md5
        callbackMap.put("mac", getMapValue(queryMap, "mac"));
        callbackMap.put("os", getMapValue(queryMap, "os"));
        //sid是下游给的click_id。 代表请求标识
        callbackMap.put("sid", getMapValue(queryMap, "sid"));
        //stime为上报时间戳。 上传过来的参数为ts
        callbackMap.put("stime", getMapValue(queryMap, "stime"));
        //获取当前时间戳 并转化为秒
        callbackMap.put("ts", (System.currentTimeMillis()/1000)+"");

        String callbackSecretkey = getMapValue(queryMap, "clientkey");
        List<String> tempList = new ArrayList<>();
        for(String key: callbackMap.keySet()){
            tempList.add(key+"="+callbackMap.get(key));
        }
        String callbackParams = String.join("&", tempList);
        String md5 = DigestUtils.md5DigestAsHex((callbackParams+callbackSecretkey).getBytes(Constants.UTF8)).toUpperCase();
        callbackParams = callbackParams + "&event_type="+getMapValue(queryMap, "event_type");
        queryString = callbackParams + "&sign="+md5;

        EncrypDES encrypDES = new EncrypDES();
        String requestAddress = encrypDES.decrypt(encryptedUrl);
        String resultStr = HttpUtils.sendGet(requestAddress, queryString);
        try {
            JSONObject resultJson = JSON.parseObject(resultStr);
            return resultJson==null?"":resultJson;
        }catch (Exception e){
            e.printStackTrace();
        }
        return resultStr;
    }

}
